package com.jiegui.utils;

import com.alibaba.fastjson.JSON;

import com.jiegui.common.exception.user.RRException;
import com.jiegui.common.utils.StringUtils;
import com.jiegui.sms.domain.SmsTemplate;
import com.jiegui.sms.model.YunPianSendSmsVo;
import com.jiegui.sms.model.YunPianTplVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 云片短信调用工具
 */
@Slf4j
public class SmsHttpUtils {

    /**
     * 发送Http请求
     *
     * @param url       请求地址
     * @param paramsMap 提交参数
     * @return 结果字符串
     * @throws IOException 请求异常
     */
    private static String post(String url, Map<String, String> paramsMap) throws IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        String responseText = "";
        CloseableHttpResponse response = null;

        HttpPost method = new HttpPost(url);
        if (paramsMap != null) {
            List<NameValuePair> paramList = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> param : paramsMap.entrySet()) {
                NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
                paramList.add(pair);
            }
            // 编码格式。发送编码格式统一用UTF-8
            String ENCODING = "UTF-8";
            method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
        }
        response = client.execute(method);
        HttpEntity entity = response.getEntity();
        if (entity != null) {responseText = EntityUtils.toString(entity);}

        response.close();
        log.info("云片响应： [{}]", responseText);
        return responseText;
    }

    /**
     * 单条短信发送,智能匹配短信模板
     *
     * @param apikey 成功注册后登录云片官网,进入后台可查看
     * @param text   需要使用已审核通过的模板或者默认模板
     * @param mobile 接收的手机号,仅支持单号码发送
     * @return 发送结果
     */
    public static YunPianSendSmsVo send(String apikey, String text, String mobile) throws RRException {
        if (StringUtils.isBlank(mobile)) {throw new RRException("短信发送参数错误");}


        Map<String, String> params = new HashMap<>();
        params.put("apikey", apikey);
        params.put("text", text);
        params.put("mobile", mobile);
        log.info("短信请求参数:[{}]", params);
        try {
            // 智能匹配模板发送接口的http地址
            String URI_SEND_SMS = "https://sms.yunpian.com/v2/sms/single_send.json";
            String response = post(URI_SEND_SMS, params);
            YunPianSendSmsVo result = JSON.parseObject(response, YunPianSendSmsVo.class);
            log.info("短信响应参数:[{}]", JSON.toJSONString(result));
            return result;
        } catch (IOException e) {
            log.error("发送短信异常: [{}]", e.getMessage());
            throw new RRException("短信发送失败");
        }
    }

    /**
     * 新增短信模板
     *
     * @param apikey   成功注册后登录云片官网,进入后台可查看
     * @param template 模板信息
     * @param callback 模板审核回调
     */
    public static YunPianTplVo tplAdd(String apikey, SmsTemplate template, String callback) throws RRException{
        Map<String, String> params = new HashMap<>();
        params.put("apikey", apikey);
        params.put("tpl_content", template.getTemplateText());
        params.put("notify_type", String.valueOf(template.getNotifyType()));
        if (StringUtils.isNotEmpty(template.getWebsite())){ params.put("website", template.getWebsite());}

        if (template.getTplType() != null) {params.put("tplType", String.valueOf(template.getTplType()));}

        params.put("callback", callback);
        log.info("短信模板新增参数:[{}]", params);

        try {
            // 短信模板新增接口的http地址
            String URI_SEND_SMS = "https://sms.yunpian.com/v2/tpl/add.json";
            String response = post(URI_SEND_SMS, params);
            // 当不在白名单内时, 可能返回YunPianBaseVo里的字段
            if (response.contains("msg")){  throw new RRException("短信模板操作失败");}

            YunPianTplVo result = JSON.parseObject(response, YunPianTplVo.class);
            log.info("短信响应参数:[{}]", JSON.toJSONString(result));
            return result;
        } catch (IOException e) {
            log.error("短信模板新增异常: [{}]", e.getMessage());
            throw new RRException("短信模板操作失败");
        }
    }

    /**
     * 修改短信模板
     *
     * @param apikey   成功注册后登录云片官网,进入后台可查看
     * @param template 模板信息
     * @param callback 模板审核回调
     */
    public static YunPianTplVo tplUpdate(String apikey, SmsTemplate template, String callback)throws RRException {
        Map<String, String> params = new HashMap<>();
        params.put("apikey", apikey);
        params.put("tpl_id", String.valueOf(template.getTplId()));
        params.put("tpl_content", template.getTemplateText());
        if (StringUtils.isNotEmpty(template.getWebsite())) {
            params.put("website", template.getWebsite());
        }
        if (template.getTplType() != null) {
            params.put("tplType", String.valueOf(template.getTplType()));
        }
        params.put("callback", callback);
        log.info("短信模板修改参数:[{}]", params);

        try {
            // 短信模板修改接口的http地址
            String URI_SEND_SMS = "https://sms.yunpian.com/v2/tpl/update.json";
            String response = post(URI_SEND_SMS, params);
            // 当不在白名单内时, 可能返回YunPianBaseVo里的字段
            if (response.contains("msg")){ throw new RRException("短信模板操作失败");}


            YunPianTplVo result = JSON.parseObject(response, YunPianTplVo.class);
            log.info("短信响应参数:[{}]", JSON.toJSONString(result));
            return result;
        } catch (IOException e) {
            log.error("短信模板修改异常: [{}]", e.getMessage());
           throw new RRException("短信模板操作失败");

        }
    }

    /**
     * 获取短信模板
     *
     * @param apikey 成功注册后登录云片官网,进入后台可查看
     * @param tpl_id 模板id
     */
    public static YunPianTplVo tplGet(String apikey, Long tpl_id) {
        Map<String, String> params = new HashMap<>();
        params.put("apikey", apikey);
        params.put("tpl_id", String.valueOf(tpl_id));
        log.info("短信模板获取参数:[{}]", params);

        try {
            // 短信模板获取接口的http地址
            String URI_SEND_SMS = "https://sms.yunpian.com/v2/tpl/get.json";
            String response = post(URI_SEND_SMS, params);
            // 当不在白名单内时, 可能返回YunPianBaseVo里的字段
            if (response.contains("msg")) {
//                throw new BusinessException(ExceptionEnum.SMS_TPL_ERROR);
            }
            YunPianTplVo result = JSON.parseObject(response, YunPianTplVo.class);
            log.info("短信响应参数:[{}]", JSON.toJSONString(result));
            return result;
        } catch (IOException e) {
            log.error("短信模板获取异常: [{}]", e.getMessage());
//            throw new BusinessException(ExceptionEnum.SMS_TPL_ERROR);
            return null;
        }
    }

    /**
     * 查询短信记录
     *
     * @param apikey       成功注册后登录云片官网,进入后台可查看
     * @param paramsMap     查询参数
     * @return 结果字符串
     * @throws IOException 请求异常
     */
    public static String query(String apikey, Map<String, String> paramsMap) throws IOException {
        Map<String, String> params = new HashMap<>();
        params.put("apikey", apikey);
        params.putAll(paramsMap);

        log.info("短信查询参数:[{}]", params);

        try {
            // 短信查询的http地址
            String URI_SEND_SMS = "https://sms.yunpian.com/v2/sms/get_record.json";
            String response = post(URI_SEND_SMS, params);
            // 当不在白名单内时, 可能返回YunPianBaseVo里的字段
            if (response.contains("msg")){  throw new RRException("短信模板操作失败");}

            log.info("短信查询响应参数:[{}]", response);
            return response;
        } catch (IOException e) {
            log.error("短信查询异常: [{}]", e.getMessage());
            throw new RRException("短信查询操作失败");
        }
    }

}
